home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / book / Chap05 / PERSPECT / Perspect.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-08-31  |  17.0 KB  |  653 lines

  1. // Perspect.c
  2. // Demonstrates Perspective Projection
  3.  
  4. #include <windows.h>            // Window defines
  5. #include <gl\gl.h>              // OpenGL
  6. #include <gl\glu.h>             // GLU library
  7. #include "resource.h"           // About box resource identifiers.
  8.  
  9. #define glRGB(x, y, z)    glColor3ub((GLubyte)x, (GLubyte)y, (GLubyte)z)
  10.  
  11. HPALETTE hPalette = NULL;
  12.  
  13. // Application name and instance storeage
  14. static LPCTSTR lpszAppName = "Perspective Projection Example";
  15. static HINSTANCE hInstance;
  16.  
  17. // Rotation amounts
  18. static GLfloat xRot = 0.0f;
  19. static GLfloat yRot = 0.0f;
  20.  
  21.  
  22. // Declaration for Window procedure
  23. LRESULT CALLBACK WndProc(   HWND    hWnd,
  24.                             UINT    message,
  25.                             WPARAM  wParam,
  26.                             LPARAM  lParam);
  27.  
  28. // Dialog procedure for about box
  29. BOOL APIENTRY AboutDlgProc (HWND hDlg, UINT message, UINT wParam, LONG lParam);
  30.  
  31. // Set Pixel Format function - forward declaration
  32. void SetDCPixelFormat(HDC hDC);
  33.  
  34.  
  35.  
  36.  
  37. // Change viewing volume and viewport.  Called when window is resized
  38. void ChangeSize(GLsizei w, GLsizei h)
  39.     {
  40.     GLfloat fAspect;
  41.  
  42.     // Prevent a divide by zero
  43.     if(h == 0)
  44.         h = 1;
  45.  
  46.     // Set Viewport to window dimensions
  47.     glViewport(0, 0, w, h);
  48.  
  49.     fAspect = (GLfloat)w/(GLfloat)h;
  50.  
  51.     // Reset coordinate system
  52.     glMatrixMode(GL_PROJECTION);
  53.     glLoadIdentity();
  54.  
  55.     // Produce the perspective projection
  56.     gluPerspective(60.0f, fAspect, 1.0, 400.0);
  57.  
  58.     glMatrixMode(GL_MODELVIEW);
  59.     glLoadIdentity();
  60.     }
  61.  
  62.  
  63.  
  64. // This function does any needed initialization on the rendering
  65. // context.  Here it sets up and initializes the lighting for
  66. // the scene.
  67. void SetupRC()
  68.     {
  69.     // Light values and coordinates
  70.     GLfloat  whiteLight[] = { 0.45f, 0.45f, 0.45f, 1.0f };
  71.     GLfloat  sourceLight[] = { 0.25f, 0.25f, 0.25f, 1.0f };
  72.     GLfloat     lightPos[] = { -50.f, 25.0f, 250.0f, 0.0f };
  73.  
  74.     glEnable(GL_DEPTH_TEST);    // Hidden surface removal
  75.     glFrontFace(GL_CCW);        // Counter clock-wise polygons face out
  76.     glEnable(GL_CULL_FACE);        // Do not calculate inside of jet
  77.  
  78.     // Enable lighting
  79.     glEnable(GL_LIGHTING);
  80.  
  81.     // Setup and enable light 0
  82.     glLightModelfv(GL_LIGHT_MODEL_AMBIENT,whiteLight);
  83.     glLightfv(GL_LIGHT0,GL_AMBIENT,sourceLight);
  84.     glLightfv(GL_LIGHT0,GL_DIFFUSE,sourceLight);
  85.     glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
  86.     glEnable(GL_LIGHT0);
  87.  
  88.     // Enable color tracking
  89.     glEnable(GL_COLOR_MATERIAL);
  90.     
  91.     // Set Material properties to follow glColor values
  92.     glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
  93.  
  94.     // Black blue background
  95.     glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
  96.     }
  97.  
  98.  
  99.  
  100.  
  101. // Called to draw scene
  102. void RenderScene(void)
  103.     {
  104.     float fZ,bZ;
  105.  
  106.     // Clear the window with current clearing color
  107.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  108.  
  109.     fZ = 100.0f;
  110.     bZ = -100.0f;
  111.  
  112.     // Save the matrix state and do the rotations
  113.     glMatrixMode(GL_MODELVIEW);
  114.     glPushMatrix();
  115.     
  116.     glTranslatef(0.0f, 0.0f, -300.0f);    
  117.     glRotatef(xRot, 1.0f, 0.0f, 0.0f);
  118.     glRotatef(yRot, 0.0f, 1.0f, 0.0f);
  119.  
  120.     
  121.  
  122.     // Set material color, Red
  123.     glRGB(192, 0, 0);
  124.  
  125.     // Front Face ///////////////////////////////////
  126.     glBegin(GL_QUADS);
  127.         // Pointing straight out Z
  128.         glNormal3f(0.0f, 0.0f, 1.0f);    
  129.  
  130.         // Left Panel
  131.         glVertex3f(-50.0f, 50.0f, fZ);
  132.         glVertex3f(-50.0f, -50.0f, fZ);
  133.         glVertex3f(-35.0f, -50.0f, fZ);
  134.         glVertex3f(-35.0f,50.0f,fZ);
  135.  
  136.         // Right Panel
  137.         glVertex3f(50.0f, 50.0f, fZ);
  138.         glVertex3f(35.0f, 50.0f, fZ);
  139.         glVertex3f(35.0f, -50.0f, fZ);
  140.         glVertex3f(50.0f,-50.0f,fZ);
  141.  
  142.         // Top Panel
  143.         glVertex3f(-35.0f, 50.0f, fZ);
  144.         glVertex3f(-35.0f, 35.0f, fZ);
  145.         glVertex3f(35.0f, 35.0f, fZ);
  146.         glVertex3f(35.0f, 50.0f,fZ);
  147.  
  148.         // Bottom Panel
  149.         glVertex3f(-35.0f, -35.0f, fZ);
  150.         glVertex3f(-35.0f, -50.0f, fZ);
  151.         glVertex3f(35.0f, -50.0f, fZ);
  152.         glVertex3f(35.0f, -35.0f,fZ);
  153.  
  154.         // Top length section ////////////////////////////
  155.         // Normal points up Y axis
  156.         glNormal3f(0.0f, 1.0f, 0.0f);
  157.         glVertex3f(-50.0f, 50.0f, fZ);
  158.         glVertex3f(50.0f, 50.0f, fZ);
  159.         glVertex3f(50.0f, 50.0f, bZ);
  160.         glVertex3f(-50.0f,50.0f,bZ);
  161.         
  162.         // Bottom section
  163.         glNormal3f(0.0f, -1.0f, 0.0f);
  164.         glVertex3f(-50.0f, -50.0f, fZ);
  165.         glVertex3f(-50.0f, -50.0f, bZ);
  166.         glVertex3f(50.0f, -50.0f, bZ);
  167.         glVertex3f(50.0f, -50.0f, fZ);
  168.  
  169.         // Left section
  170.         glNormal3f(1.0f, 0.0f, 0.0f);
  171.         glVertex3f(50.0f, 50.0f, fZ);
  172.         glVertex3f(50.0f, -50.0f, fZ);
  173.         glVertex3f(50.0f, -50.0f, bZ);
  174.         glVertex3f(50.0f, 50.0f, bZ);
  175.  
  176.         // Right Section
  177.         glNormal3f(-1.0f, 0.0f, 0.0f);
  178.         glVertex3f(-50.0f, 50.0f, fZ);
  179.         glVertex3f(-50.0f, 50.0f, bZ);
  180.         glVertex3f(-50.0f, -50.0f, bZ);
  181.         glVertex3f(-50.0f, -50.0f, fZ);
  182.     glEnd();
  183.  
  184.  
  185.     glFrontFace(GL_CW);        // clock-wise polygons face out
  186.  
  187.     // Set material color, Red
  188.     glBegin(GL_QUADS);
  189.         // Back section
  190.         // Pointing straight out Z
  191.         glNormal3f(0.0f, 0.0f, -1.0f);    
  192.  
  193.         // Left Panel
  194.         glVertex3f(-50.0f, 50.0f, bZ);
  195.         glVertex3f(-50.0f, -50.0f, bZ);
  196.         glVertex3f(-35.0f, -50.0f, bZ);
  197.         glVertex3f(-35.0f,50.0f,bZ);
  198.  
  199.         // Right Panel
  200.         glVertex3f(50.0f, 50.0f, bZ);
  201.         glVertex3f(35.0f, 50.0f, bZ);
  202.         glVertex3f(35.0f, -50.0f, bZ);
  203.         glVertex3f(50.0f,-50.0f,bZ);
  204.  
  205.         // Top Panel
  206.         glVertex3f(-35.0f, 50.0f, bZ);
  207.         glVertex3f(-35.0f, 35.0f, bZ);
  208.         glVertex3f(35.0f, 35.0f, bZ);
  209.         glVertex3f(35.0f, 50.0f,bZ);
  210.  
  211.         // Bottom Panel
  212.         glVertex3f(-35.0f, -35.0f, bZ);
  213.         glVertex3f(-35.0f, -50.0f, bZ);
  214.         glVertex3f(35.0f, -50.0f, bZ);
  215.         glVertex3f(35.0f, -35.0f,bZ);
  216.     
  217.     // Insides /////////////////////////////
  218.         glRGB(192, 192, 192);
  219.  
  220.         // Normal points up Y axis
  221.         glNormal3f(0.0f, 1.0f, 0.0f);
  222.         glVertex3f(-35.0f, 35.0f, fZ);
  223.         glVertex3f(35.0f, 35.0f, fZ);
  224.         glVertex3f(35.0f, 35.0f, bZ);
  225.         glVertex3f(-35.0f,35.0f,bZ);
  226.         
  227.         // Bottom section
  228.         glNormal3f(0.0f, 1.0f, 0.0f);
  229.         glVertex3f(-35.0f, -35.0f, fZ);
  230.         glVertex3f(-35.0f, -35.0f, bZ);
  231.         glVertex3f(35.0f, -35.0f, bZ);
  232.         glVertex3f(35.0f, -35.0f, fZ);
  233.  
  234.         // Left section
  235.         glNormal3f(1.0f, 0.0f, 0.0f);
  236.         glVertex3f(-35.0f, 35.0f, fZ);
  237.         glVertex3f(-35.0f, 35.0f, bZ);
  238.         glVertex3f(-35.0f, -35.0f, bZ);
  239.         glVertex3f(-35.0f, -35.0f, fZ);
  240.  
  241.         // Right Section
  242.         glNormal3f(-1.0f, 0.0f, 0.0f);
  243.         glVertex3f(35.0f, 35.0f, fZ);
  244.         glVertex3f(35.0f, -35.0f, fZ);
  245.         glVertex3f(35.0f, -35.0f, bZ);
  246.         glVertex3f(35.0f, 35.0f, bZ);
  247.     glEnd();
  248.  
  249.  
  250.     glFrontFace(GL_CCW);        // Counter clock-wise polygons face out
  251.  
  252.     // Restore the matrix state
  253.     glPopMatrix();    // Modelview matrix
  254.  
  255.     // Flush drawing commands
  256.     glFlush();
  257.     }
  258.  
  259.  
  260. // Select the pixel format for a given device context
  261. void SetDCPixelFormat(HDC hDC)
  262.     {
  263.     int nPixelFormat;
  264.  
  265.     static PIXELFORMATDESCRIPTOR pfd = {
  266.         sizeof(PIXELFORMATDESCRIPTOR),  // Size of this structure
  267.         1,                                                              // Version of this structure    
  268.         PFD_DRAW_TO_WINDOW |                    // Draw to Window (not to bitmap)
  269.         PFD_SUPPORT_OPENGL |                    // Support OpenGL calls in window
  270.         PFD_DOUBLEBUFFER,                       // Double buffered
  271.         PFD_TYPE_RGBA,                          // RGBA Color mode
  272.         24,                                     // Want 24bit color 
  273.         0,0,0,0,0,0,                            // Not used to select mode
  274.         0,0,                                    // Not used to select mode
  275.         0,0,0,0,0,                              // Not used to select mode
  276.         16,                                     // Size of depth buffer
  277.         0,                                      // Not used to select mode
  278.         0,                                      // Not used to select mode
  279.         PFD_MAIN_PLANE,                         // Draw in main plane
  280.         0,                                      // Not used to select mode
  281.         0,0,0 };                                // Not used to select mode
  282.  
  283.     // Choose a pixel format that best matches that described in pfd
  284.     nPixelFormat = ChoosePixelFormat(hDC, &pfd);
  285.  
  286.     // Set the pixel format for the device context
  287.     SetPixelFormat(hDC, nPixelFormat, &pfd);
  288.     }
  289.  
  290.  
  291.  
  292. // If necessary, creates a 3-3-2 palette for the device context listed.
  293. HPALETTE GetOpenGLPalette(HDC hDC)
  294.     {
  295.     HPALETTE hRetPal = NULL;    // Handle to palette to be created
  296.     PIXELFORMATDESCRIPTOR pfd;    // Pixel Format Descriptor
  297.     LOGPALETTE *pPal;            // Pointer to memory for logical palette
  298.     int nPixelFormat;            // Pixel format index
  299.     int nColors;                // Number of entries in palette
  300.     int i;                        // Counting variable
  301.     BYTE RedRange,GreenRange,BlueRange;
  302.                                 // Range for each color entry (7,7,and 3)
  303.  
  304.  
  305.     // Get the pixel format index and retrieve the pixel format description
  306.     nPixelFormat = GetPixelFormat(hDC);
  307.     DescribePixelFormat(hDC, nPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
  308.  
  309.     // Does this pixel format require a palette?  If not, do not create a
  310.     // palette and just return NULL
  311.     if(!(pfd.dwFlags & PFD_NEED_PALETTE))
  312.         return NULL;
  313.  
  314.     // Number of entries in palette.  8 bits yeilds 256 entries
  315.     nColors = 1 << pfd.cColorBits;    
  316.  
  317.     // Allocate space for a logical palette structure plus all the palette entries
  318.     pPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) +nColors*sizeof(PALETTEENTRY));
  319.  
  320.     // Fill in palette header 
  321.     pPal->palVersion = 0x300;        // Windows 3.0
  322.     pPal->palNumEntries = nColors; // table size
  323.  
  324.     // Build mask of all 1's.  This creates a number represented by having
  325.     // the low order x bits set, where x = pfd.cRedBits, pfd.cGreenBits, and
  326.     // pfd.cBlueBits.  
  327.     RedRange = (1 << pfd.cRedBits) -1;
  328.     GreenRange = (1 << pfd.cGreenBits) - 1;
  329.     BlueRange = (1 << pfd.cBlueBits) -1;
  330.  
  331.     // Loop through all the palette entries
  332.     for(i = 0; i < nColors; i++)
  333.         {
  334.         // Fill in the 8-bit equivalents for each component
  335.         pPal->palPalEntry[i].peRed = (i >> pfd.cRedShift) & RedRange;
  336.         pPal->palPalEntry[i].peRed = (unsigned char)(
  337.             (double) pPal->palPalEntry[i].peRed * 255.0 / RedRange);
  338.  
  339.         pPal->palPalEntry[i].peGreen = (i >> pfd.cGreenShift) & GreenRange;
  340.         pPal->palPalEntry[i].peGreen = (unsigned char)(
  341.             (double)pPal->palPalEntry[i].peGreen * 255.0 / GreenRange);
  342.  
  343.         pPal->palPalEntry[i].peBlue = (i >> pfd.cBlueShift) & BlueRange;
  344.         pPal->palPalEntry[i].peBlue = (unsigned char)(
  345.             (double)pPal->palPalEntry[i].peBlue * 255.0 / BlueRange);
  346.  
  347.         pPal->palPalEntry[i].peFlags = (unsigned char) NULL;
  348.         }
  349.         
  350.  
  351.     // Create the palette
  352.     hRetPal = CreatePalette(pPal);
  353.  
  354.     // Go ahead and select and realize the palette for this device context
  355.     SelectPalette(hDC,hRetPal,FALSE);
  356.     RealizePalette(hDC);
  357.  
  358.     // Free the memory used for the logical palette structure
  359.     free(pPal);
  360.  
  361.     // Return the handle to the new palette
  362.     return hRetPal;
  363.     }
  364.  
  365.  
  366. // Entry point of all Windows programs
  367. int APIENTRY WinMain(   HINSTANCE       hInst,
  368.                         HINSTANCE       hPrevInstance,
  369.                         LPSTR           lpCmdLine,
  370.                         int                     nCmdShow)
  371.     {
  372.     MSG                     msg;            // Windows message structure
  373.     WNDCLASS        wc;                     // Windows class structure
  374.     HWND            hWnd;           // Storeage for window handle
  375.  
  376.     hInstance = hInst;
  377.  
  378.     // Register Window style
  379.     wc.style                = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
  380.     wc.lpfnWndProc          = (WNDPROC) WndProc;
  381.     wc.cbClsExtra           = 0;
  382.     wc.cbWndExtra           = 0;
  383.     wc.hInstance            = hInstance;
  384.     wc.hIcon                        = NULL;
  385.     wc.hCursor                      = LoadCursor(NULL, IDC_ARROW);
  386.     
  387.     // No need for background brush for OpenGL window
  388.     wc.hbrBackground        = NULL;         
  389.     
  390.     wc.lpszMenuName         = MAKEINTRESOURCE(IDR_MENU);
  391.     wc.lpszClassName        = lpszAppName;
  392.  
  393.     // Register the window class
  394.     if(RegisterClass(&wc) == 0)
  395.         return FALSE;
  396.  
  397.  
  398.     // Create the main application window
  399.     hWnd = CreateWindow(
  400.                 lpszAppName,
  401.                 lpszAppName,
  402.                 
  403.                 // OpenGL requires WS_CLIPCHILDREN and WS_CLIPSIBLINGS
  404.                 WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  405.     
  406.                 // Window position and size
  407.                 50, 50,
  408.                 400, 400,
  409.                 NULL,
  410.                 NULL,
  411.                 hInstance,
  412.                 NULL);
  413.  
  414.     // If window was not created, quit
  415.     if(hWnd == NULL)
  416.         return FALSE;
  417.  
  418.  
  419.     // Display the window
  420.     ShowWindow(hWnd,SW_SHOW);
  421.     UpdateWindow(hWnd);
  422.  
  423.     // Process application messages until the application closes
  424.     while( GetMessage(&msg, NULL, 0, 0))
  425.         {
  426.         TranslateMessage(&msg);
  427.         DispatchMessage(&msg);
  428.         }
  429.  
  430.     return msg.wParam;
  431.     }
  432.  
  433.  
  434.  
  435.  
  436. // Window procedure, handles all messages for this program
  437. LRESULT CALLBACK WndProc(       HWND    hWnd,
  438.                             UINT    message,
  439.                             WPARAM  wParam,
  440.                             LPARAM  lParam)
  441.     {
  442.     static HGLRC hRC;               // Permenant Rendering context
  443.     static HDC hDC;                 // Private GDI Device context
  444.  
  445.     switch (message)
  446.         {
  447.         // Window creation, setup for OpenGL
  448.         case WM_CREATE:
  449.             // Store the device context
  450.             hDC = GetDC(hWnd);              
  451.  
  452.             // Select the pixel format
  453.             SetDCPixelFormat(hDC);          
  454.  
  455.             hPalette = GetOpenGLPalette(hDC);
  456.  
  457.             // Create the rendering context and make it current
  458.             hRC = wglCreateContext(hDC);
  459.             wglMakeCurrent(hDC, hRC);
  460.             SetupRC();
  461.  
  462.             break;
  463.  
  464.         // Window is being destroyed, cleanup
  465.         case WM_DESTROY:
  466.             // Deselect the current rendering context and delete it
  467.             wglMakeCurrent(hDC,NULL);
  468.             wglDeleteContext(hRC);
  469.  
  470.             if(hPalette != NULL)
  471.                 DeleteObject(hPalette);
  472.  
  473.             // Tell the application to terminate after the window
  474.             // is gone.
  475.             PostQuitMessage(0);
  476.             break;
  477.  
  478.         // Window is resized.
  479.         case WM_SIZE:
  480.             // Call our function which modifies the clipping
  481.             // volume and viewport
  482.             ChangeSize(LOWORD(lParam), HIWORD(lParam));
  483.             break;
  484.  
  485.  
  486.         // The painting function.  This message sent by Windows 
  487.         // whenever the screen needs updating.
  488.         case WM_PAINT:
  489.             {
  490.             // Call OpenGL drawing code
  491.             RenderScene();
  492.  
  493.             SwapBuffers(hDC);
  494.  
  495.             // Validate the newly painted client area
  496.             ValidateRect(hWnd,NULL);
  497.             }
  498.             break;
  499.  
  500.         // Windows is telling the application that it may modify
  501.         // the system palette.  This message in essance asks the 
  502.         // application for a new palette.
  503.         case WM_QUERYNEWPALETTE:
  504.             // If the palette was created.
  505.             if(hPalette)
  506.                 {
  507.                 int nRet;
  508.  
  509.                 // Selects the palette into the current device context
  510.                 SelectPalette(hDC, hPalette, FALSE);
  511.  
  512.                 // Map entries from the currently selected palette to
  513.                 // the system palette.  The return value is the number 
  514.                 // of palette entries modified.
  515.                 nRet = RealizePalette(hDC);
  516.  
  517.                 // Repaint, forces remap of palette in current window
  518.                 InvalidateRect(hWnd,NULL,FALSE);
  519.  
  520.                 return nRet;
  521.                 }
  522.             break;
  523.  
  524.     
  525.         // This window may set the palette, even though it is not the 
  526.         // currently active window.
  527.         case WM_PALETTECHANGED:
  528.             // Don't do anything if the palette does not exist, or if
  529.             // this is the window that changed the palette.
  530.             if((hPalette != NULL) && ((HWND)wParam != hWnd))
  531.                 {
  532.                 // Select the palette into the device context
  533.                 SelectPalette(hDC,hPalette,FALSE);
  534.  
  535.                 // Map entries to system palette
  536.                 RealizePalette(hDC);
  537.                 
  538.                 // Remap the current colors to the newly realized palette
  539.                 UpdateColors(hDC);
  540.                 return 0;
  541.                 }
  542.             break;
  543.  
  544.         // Key press, check for arrow keys to do cube rotation.
  545.         case WM_KEYDOWN:
  546.             {
  547.             if(wParam == VK_UP)
  548.                 xRot-= 5.0f;
  549.  
  550.             if(wParam == VK_DOWN)
  551.                 xRot += 5.0f;
  552.  
  553.             if(wParam == VK_LEFT)
  554.                 yRot -= 5.0f;
  555.  
  556.             if(wParam == VK_RIGHT)
  557.                 yRot += 5.0f;
  558.  
  559.             xRot = (GLfloat)((const int)xRot % 360);
  560.             yRot = (GLfloat)((const int)yRot % 360);
  561.  
  562.             InvalidateRect(hWnd,NULL,FALSE);
  563.             }
  564.             break;
  565.  
  566.         // A menu command
  567.         case WM_COMMAND:
  568.             {
  569.             switch(LOWORD(wParam))
  570.                 {
  571.                 // Exit the program
  572.                 case ID_FILE_EXIT:
  573.                     DestroyWindow(hWnd);
  574.                     break;
  575.  
  576.                 // Display the about box
  577.                 case ID_HELP_ABOUT:
  578.                     DialogBox (hInstance,
  579.                         MAKEINTRESOURCE(IDD_DIALOG_ABOUT),
  580.                         hWnd,
  581.                         AboutDlgProc);
  582.                     break;
  583.                 }
  584.             }
  585.             break;
  586.  
  587.  
  588.     default:   // Passes it on if unproccessed
  589.         return (DefWindowProc(hWnd, message, wParam, lParam));
  590.  
  591.     }
  592.  
  593.     return (0L);
  594.     }
  595.  
  596.  
  597.  
  598.  
  599. // Dialog procedure.
  600. BOOL APIENTRY AboutDlgProc (HWND hDlg, UINT message, UINT wParam, LONG lParam)
  601.     {
  602.     
  603.     switch (message)
  604.     {
  605.         // Initialize the dialog box
  606.         case WM_INITDIALOG:
  607.             {
  608.             int i;
  609.             GLenum glError;
  610.  
  611.             // glGetString demo
  612.             SetDlgItemText(hDlg,IDC_OPENGL_VENDOR,glGetString(GL_VENDOR));
  613.             SetDlgItemText(hDlg,IDC_OPENGL_RENDERER,glGetString(GL_RENDERER));
  614.             SetDlgItemText(hDlg,IDC_OPENGL_VERSION,glGetString(GL_VERSION));
  615.             SetDlgItemText(hDlg,IDC_OPENGL_EXTENSIONS,glGetString(GL_EXTENSIONS));
  616.  
  617.             // gluGetString demo
  618.             SetDlgItemText(hDlg,IDC_GLU_VERSION,gluGetString(GLU_VERSION));
  619.             SetDlgItemText(hDlg,IDC_GLU_EXTENSIONS,gluGetString(GLU_EXTENSIONS));
  620.  
  621.  
  622.             // Display any recent error messages
  623.             i = 0;
  624.             do {
  625.                 glError = glGetError();
  626.                 SetDlgItemText(hDlg,IDC_ERROR1+i,gluErrorString(glError));
  627.                 i++;
  628.                 }
  629.             while(i < 6 && glError != GL_NO_ERROR);
  630.  
  631.  
  632.             return (TRUE);
  633.             }
  634.             break;
  635.  
  636.         // Process command messages
  637.         case WM_COMMAND:      
  638.             {
  639.             // Validate and Make the changes
  640.             if(LOWORD(wParam) == IDOK)
  641.                 EndDialog(hDlg,TRUE);
  642.             }
  643.             break;
  644.  
  645.         // Closed from sysbox
  646.         case WM_CLOSE:
  647.             EndDialog(hDlg,TRUE);
  648.             break;
  649.         }
  650.  
  651.     return FALSE;
  652.     }
  653.